package com.autumn.gateway.server.fallback;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import com.autumn.common.api.web.vo.ApiObjectResponse;
import com.autumn.util.IAutumnError;
import com.autumn.util.json.JsonUtils;
import com.netflix.zuul.context.RequestContext;

/**
 * 服务回退
 * 
 * @author 老码农
 *         <p>
 *         Description
 *         </p>
 * @date 2017-12-24 00:59:42
 */
@Component
public class ServerFallback implements ZuulFallbackProvider {

	/**
	 * 日志
	 */
	private final static Log logger = LogFactory.getLog(ServerFallback.class);

	public static final String DEFAULT_ERROR_MESSAGE = "网络出错,请稍后再试";

	@Override
	public String getRoute() {
		// 所有服务
		return "*";
	}

	@Override
	public ClientHttpResponse fallbackResponse() {
		return new ClientHttpResponse() {
			@Override
			public InputStream getBody() throws IOException {
				RequestContext ctx = RequestContext.getCurrentContext();
				HttpServletRequest request = ctx.getRequest();
				logger.warn(DEFAULT_ERROR_MESSAGE + ":url->" + request.getRequestURI());
				ApiObjectResponse res = ApiObjectResponse.error(IAutumnError.SystemErrorCode.NETWORK_ERRORCODE,
						DEFAULT_ERROR_MESSAGE, request.getRequestURI());
				return new ByteArrayInputStream(JsonUtils.toJSONString(res).getBytes(StandardCharsets.UTF_8));
			}

			@Override
			public HttpHeaders getHeaders() {
				HttpHeaders headers = new HttpHeaders();
				headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
				return headers;
			}

			/**
			 * 网关向api服务请求是失败了，但是消费者客户端向网关发起的请求是OK的， 不应该把api的404,500等问题抛给客户端
			 * 网关和api服务集群对于客户端来说是黑盒子
			 */
			@Override
			public HttpStatus getStatusCode() throws IOException {
				return HttpStatus.OK;
			}

			@Override
			public int getRawStatusCode() throws IOException {
				return HttpStatus.OK.value();
			}

			@Override
			public String getStatusText() throws IOException {
				return HttpStatus.OK.getReasonPhrase();
			}

			@Override
			public void close() {

			}

		};
	}

}
